package com.rupertjones.globalcron.web.model;

import com.rupertjones.globalcron.domain.JobDescriptor;
import com.rupertjones.globalcron.domain.JobExecutionLog;
import org.apache.log4j.Logger;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.Duration;
import org.joda.time.Period;
import org.quartz.Trigger;

import java.util.List;

import static com.rupertjones.globalcron.web.util.JodaTimeFormatter.format;

/**
 * <p>GlobalCron &copy Rupert Jones 2011</p>
 *
 * @author rup
 */
public class DisplayableJob {
    private static final Logger LOG = Logger.getLogger(DisplayableJob.class);
    private JobDescriptor jobDescriptor;
    private Trigger trigger;

    public DisplayableJob(JobDescriptor descriptor, Trigger trigger) {
        this.jobDescriptor = descriptor;
        this.trigger = trigger;
    }

    public DisplayableJob(JobDescriptor descriptor) {
        this.jobDescriptor = descriptor;
    }

    public int getId() {
        return jobDescriptor.getId();
    }

    public String getName() {
        return jobDescriptor.getName();
    }

    public String getCron() {
        return jobDescriptor.getCron();
    }

    public String getTimezone() {
        return jobDescriptor.getTimezone();
    }

    public String getScript() {
        return jobDescriptor.getScript();
    }

    public boolean isSaveOutput() {
        return jobDescriptor.isSaveOutput();
    }

    public boolean isWaitForCompletion() {
        return jobDescriptor.isWaitForCompletion();
    }

    public long getWaitAfter() {
        return jobDescriptor.getWaitAfter();
    }

    public boolean isAllowAdhocExec() {
        return isEnabled() && jobDescriptor.isAllowAdhocExec();
    }

    public List<JobExecutionLog> getLogs() {
        return jobDescriptor.getLogs();
    }

    public String getLastModified() {
        return format("EEE dd MMM yyyy HH:mm:ss", new DateTime(jobDescriptor.getLastModified()));
    }

    public String getHostname() {
        return jobDescriptor.getHost().getHostname();
    }

    public String getLastFireTimeFormattedInExecutionTimezone() {
        DateTime lastFire = getLastFireTimeAsDate();
        if(lastFire != null) {
            return format("EEE dd MMM yyyy HH:mm:ss", jobDescriptor.getLastFireAtExecutionTimezone());
        }
        return "";
    }

    public String getNextFireTimeFormattedInExecutionTimezone() {
        DateTime nextFireTime = getNextFireTimeAsDate();
        if(nextFireTime != null) {
            return format("EEE dd MMM yyyy HH:mm:ss", jobDescriptor.getNextFireAtExecutionTimezone());
        }
        return "n/a";
    }

    public String getNextFireTimeFormatted() {
        DateTime nextFireTime = getNextFireTimeAsDate();
        if(nextFireTime != null) {
            return format("EEE dd MMM yyyy HH:mm:ss", nextFireTime);
        }
        return "n/a";
    }

    public String getTimeToNextFire() {
        return printDuration(new DateTime(), getNextFireTimeAsDate());
    }

    public String getTimeSinceLastFire() {
       return printDuration(getLastFireTimeAsDate(), new DateTime());
    }

    private String printDuration(DateTime from, DateTime to) {
        if(to == null || from == null) {
            return "n/a";
        }

        Duration duration = new Duration(from, to);
        Period period = duration.toPeriod();
        return format(period);
    }

    public String getLastFireTimeFormatted() {
        DateTime lastFireTimeAsDate = getLastFireTimeAsDate();
        if (lastFireTimeAsDate != null) {
            return format("EEE dd MMM yyyy HH:mm:ss", lastFireTimeAsDate);
        }
        return "n/a";
    }

    public DateTime getLastFireTimeAsDate() {
        return jobDescriptor.getLastFire();
    }

    public DateTime getNextFireTimeAsDate() {
        if(isEnabled()) {
            return jobDescriptor.getNextFire();
        }
        return null;
    }

    public boolean isEnabled() {
        return jobDescriptor.isEnabled();
    }

    public boolean isScheduled() {
        return hasTrigger();
    }

    public boolean hasTrigger() {
        return trigger != null;
    }

    public JobDescriptor getJobDescriptor() {
        return jobDescriptor;
    }

    public JobExecutionLog getLog(int id) {
        for (JobExecutionLog log : jobDescriptor.getLogs()) {
            if (log.getId() == id) {
                return log;
            }
        }
        return null;
    }

    public DateTimeZone getTimezoneAsObject() {
        return jobDescriptor.getTimezoneAsObject();
    }
}
